package com.doctcloud.hisinfo.common.service.impl;

import com.doctcloud.common.core.utils.StringUtils;
import com.doctcloud.common.mongo.service.impl.BaseMongoServiceImpl;
import com.doctcloud.hisinfo.common.service.IDeptDescInfoService;
import com.doctcloud.hisinfo.histable.document.DeptDescInfoDo;
import com.doctcloud.hisinfo.histable.domain.comm.DeptDictDo;
import com.doctcloud.hisinfo.histable.document.FileInfoDo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 科室附属信息服务实现类
 * <p>
 * 优化点：
 * 1. 使用 @Slf4j 简化日志记录
 * 2. 使用 @RequiredArgsConstructor 替代 @Autowired，更符合构造器注入规范
 * 3. 删除无用的 MongoTemplate 注入
 * 4. 为方法添加 @Transactional 事务支持
 * 5. 优化方法命名，使其更符合业务语义
 * 6. 细化日志输出，便于问题追踪
 * 7. 对 List 类型的 fileUrl 字段进行安全处理，避免空指针异常并明确其映射关系
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeptDescInfoServiceImpl extends BaseMongoServiceImpl<DeptDescInfoDo, String> implements IDeptDescInfoService {

    /**
     * 根据科室代码获取科室详细信息
     *
     * @param deptCode 科室代码
     * @return 科室详细信息对象，若不存在则返回 null
     */
    @Override
    public DeptDescInfoDo getDeptInfoByCode(String deptCode) {
        log.debug("开始查询科室代码为 [{}] 的科室详细信息", deptCode);

        if (StringUtils.isEmpty(deptCode)) {
            log.warn("查询科室信息失败：科室代码为空");
            return null;
        }

        DeptDescInfoDo result = findById(deptCode).orElse(null);

        if (result == null) {
            log.info("未找到科室代码为 [{}] 的科室详细信息", deptCode);
        } else {
            log.debug("成功查询到科室代码为 [{}] 的科室详细信息", deptCode);
        }

        return result;
    }

    /**
     * 根据科室字典信息创建或更新科室详细信息
     *
     * @param deptDict 科室字典信息对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrUpdateByDeptDict(DeptDictDo deptDict) {
        log.debug("开始创建或更新科室信息：{}", deptDict);

        // 1. 验证输入参数
        if (deptDict == null) {
            log.warn("创建或更新科室信息失败：输入的科室字典信息为空");
            return;
        }

        // 2. 提取并验证关键字段
        String deptCode = deptDict.getDeptCode();
        String deptName = deptDict.getDeptName();
        String deptDesc = deptDict.getDeptDesc();

        if (StringUtils.isEmpty(deptCode) || StringUtils.isEmpty(deptName) || StringUtils.isEmpty(deptDesc)) {
            log.warn("创建或更新科室信息失败：科室代码[{}]、名称[{}]或描述[{}]不能为空",
                    deptCode, deptName, deptDesc);
            return;
        }

        try {
            // 3. 查询现有科室信息
            DeptDescInfoDo deptDescInfo = findById(deptCode).orElse(new DeptDescInfoDo());

            // 4. 更新科室信息
            deptDescInfo.setDeptCode(deptCode);
            deptDescInfo.setDeptName(deptName);
            deptDescInfo.setDeptDescDetail(deptDesc);
            deptDescInfo.setBuckets(deptDict.getBuckets());

            // --- 针对 fileUrl (List<String>) 的特别优化 ---
            // 为了避免直接引用传递可能带来的潜在问题（虽然在此场景下影响不大），
            // 以及确保目标对象的字段是一个确定的、独立的列表，我们创建一个新的 ArrayList。
            // 同时，使用 Objects.requireNonNullElse 避免空指针异常，如果源列表为 null，则设置为一个空列表。
            List<FileInfoDo> sourceFileUrls = deptDescInfo.getFileInfos();
            if (sourceFileUrls != null) {
                deptDescInfo.setFileInfos(new ArrayList<>(sourceFileUrls));
                log.trace("成功为科室 [{}] 设置了 {} 个文件URL", deptCode, sourceFileUrls.size());
            } else {
                // 如果源数据中没有文件URL，可以选择设置为空列表或保持不变。
                // 设置为空列表更清晰，表示"没有文件"。
                deptDescInfo.setFileInfos(Collections.emptyList());
                log.trace("科室 [{}] 没有关联的文件URL，已设置为空列表", deptCode);
            }

            // 5. 保存更新后的信息
            saveOrUpdate(deptDescInfo);

            log.info("成功创建或更新科室代码为 [{}] 的科室信息", deptCode);
        } catch (Exception e) {
            log.error("创建或更新科室代码为 [{}] 的科室信息失败", deptCode, e);
            throw e; // 抛出异常，触发事务回滚
        }
    }

    /**
     * 根据科室代码删除科室详细信息
     *
     * @param deptCode 科室代码
     * @return 删除成功返回 true，否则返回 false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDeptInfoByCode(String deptCode) {
        log.debug("开始删除科室代码为 [{}] 的科室详细信息", deptCode);

        if (StringUtils.isEmpty(deptCode)) {
            log.warn("删除科室信息失败：科室代码为空");
            return false;
        }

        try {
            boolean result = deleteById(deptCode);

            if (result) {
                log.info("成功删除科室代码为 [{}] 的科室详细信息", deptCode);
            } else {
                log.warn("删除科室信息失败：未找到科室代码为 [{}] 的科室详细信息", deptCode);
            }

            return result;
        } catch (Exception e) {
            log.error("删除科室代码为 [{}] 的科室信息时发生异常", deptCode, e);
            throw e; // 抛出异常，触发事务回滚
        }
    }
}